package cn.lg.soar.boot.fc.service.impl;

import cn.lg.soar.boot.client.entity.ClientUser;
import cn.lg.soar.boot.client.service.ClientUserService;
import cn.lg.soar.boot.fc.entity.*;
import cn.lg.soar.boot.fc.entity.Process;
import cn.lg.soar.boot.fc.service.*;
import cn.lg.soar.common.algorithm.CryptoUtils;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.model.HttpResult;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.FileUtil;
import cn.lg.soar.common.util.data.RandomUtil;
import cn.lg.soar.database.query.SqueryWapper;
import cn.lg.soar.general.entity.FileMetadata;
import cn.lg.soar.general.manager.FileTemplateManager;
import cn.lg.soar.general.s3.FileTemplate;
import cn.lg.soar.general.service.IFileMetadataService;
import cn.lg.soar.system.auth.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.lg.soar.database.base.service.impl.BaseServiceImpl;
import cn.lg.soar.boot.fc.mapper.TenancyRoomMapper;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;

/**
 * 租房表
 * @author ZhuanZ（无密码）
 * @since 2025-01-18
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Service
public class TenancyRoomServiceImpl extends BaseServiceImpl<TenancyRoomMapper, TenancyRoom> implements TenancyRoomService {

    @Resource
    private RoomService roomService;
    @Autowired
    protected FormResultService formResultService;
    @Autowired
    protected TenancyRoomRecordService recordService;
    @Autowired
    protected FinanceService financeService;
    @Autowired
    protected LeaseService leaseService;
    @Autowired
    protected IUserService userService;
    @Autowired
    protected ProcessService processService;
    @Resource
    private ProcessApplyService processApplyService;
    /** 客户端用户信息服务 */
    @Autowired private ClientUserService clientUserService;
    @Autowired
    private IFileMetadataService fileMetadataService;
    @Autowired
    private FileTemplateManager uploadTemplateManager;


    private SqueryWapper<Lease> squeryWapper;

    private SqueryWapper<Process> squeryWapperProcess;

    /**
     * 用户申请租房
     */
    @Transactional
    public HttpResult<Void> applyRoom(Long customFormId,Long roomId,Long leaseId,Long formApplyId) {
        FormResult formResult = formResultService.getById(customFormId);
        if (null == formResult){
            System.out.println("===============1用户提交表单信息为空！");
            return HttpResult.fail("B0000", I18n.build("用户提交表单信息为空！"));
        }
        Room room = roomService.getById(roomId);
        if (null == room){
            System.out.println("===============1房间信息为空！");
            return HttpResult.fail("B0000", I18n.build("房间信息为空！"));
        }
        if(room.getTenancyWay() == 1 && leaseId == null){
            System.out.println("===============1合租ID为空！");
            return HttpResult.fail("B0000", I18n.build("合租ID为空！"));
        }
        TenancyRoom tenancyRoom = new TenancyRoom();
        tenancyRoom.setRoomId(roomId);
        tenancyRoom.setLeaseId(leaseId);
        tenancyRoom.setFormResultId(customFormId);
        tenancyRoom.setFormApplyId(formApplyId);
        tenancyRoom.setUserId(formResult.getSubmitUserId());
        tenancyRoom.setApplicantId(formResult.getSubmitApplicantId());
        tenancyRoom.setCampusId(room.getCampusId());
        tenancyRoom.setBuildingId(room.getBuildingId());
        tenancyRoom.setUnitId(room.getUnitId());
        tenancyRoom.setFloorId(room.getCampusId());
        tenancyRoom.setPayWay(room.getPayWay());
        tenancyRoom.setTenancyWay(room.getTenancyWay());
        tenancyRoom.setTenancyState(0);
        tenancyRoom.setContinueState(0);
        tenancyRoom.setApplyTime(formResult.getSubmitTime());
        AssertUtil.isTrue(super.save(tenancyRoom), "创建失败");

        return HttpResult.success();
    }

    /**
     * 合同签约
     */
    @Transactional
    public HttpResult<Void> contractSign(Long id) {
        //TODO 合同签约
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(id);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        //TODO 重新计算租金
//        BigDecimal billAmount = new BigDecimal(99.99);
        BigDecimal billAmount = tenancyRoom.getWaitPay();
//        LocalDateTime now = LocalDateTime.now();
//        LocalDateTime endTime = now;
//        if(tenancyRoom.getPayWay() == 0){
//            endTime = now.plusMonths(1);
//        }else if(tenancyRoom.getPayWay() == 1){
//            endTime = now.plusMonths(3);
//        }else if(tenancyRoom.getPayWay() == 2){
//            endTime = now.plusMonths(6);
//        }else if(tenancyRoom.getPayWay() == 3){
//            endTime = now.plusMonths(12);
//        }

//        tenancyRoom.setWaitPay(billAmount);

//        tenancyRoom.setAlreadyPay(tenancyRoom.getWaitPay());
//        tenancyRoom.setWaitPay(new BigDecimal(0));
        tenancyRoom.setTenancyState(2);
        tenancyRoom.setContinueState(0);
//        tenancyRoom.setFirstPayTime(now);
//        tenancyRoom.setMoveTime(now);
//        tenancyRoom.setEndTime(endTime);
        AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");

        // 生成账单
        Finance record = new Finance();
        record.setTenancyId(tenancyRoom.getId());
        record.setFormResultId(tenancyRoom.getFormResultId());
        record.setUserId(tenancyRoom.getUserId());
        record.setApplicantId(tenancyRoom.getApplicantId());
        record.setRoomId(tenancyRoom.getRoomId());
        record.setTenancyWay(tenancyRoom.getTenancyWay());
        record.setLeaseId(tenancyRoom.getLeaseId());
        record.setContractId(tenancyRoom.getContractId());
        record.setContractCode(tenancyRoom.getContractCode());
        record.setPayWay(tenancyRoom.getPayWay());
        record.setIsContinue(0);
        record.setApplyTime(tenancyRoom.getApplyTime());
        record.setExamineTime(tenancyRoom.getExamineTime());
        record.setBillAmount(billAmount);
        record.setUnpaidAmount(billAmount);
        AssertUtil.isTrue(financeService.save(record), "创建失败");

//        // 更新房间使用情况
//        if(tenancyRoom.getTenancyWay() == 0){
//            // 更新整租房间使用情况
//            Room room = roomService.getById(tenancyRoom.getRoomId());
//            if(room != null){
//                room.setUseState(2);
//                if(tenancyRoom.getTenancyWay() == 0){
//                    room.setIsFull(1);
//                }
//                AssertUtil.isTrue(roomService.updateById(room), "更新失败");
//            }
//        }else{
//            // 更新合租房间使用情况
//            Lease lease = leaseService.getById(tenancyRoom.getLeaseId());
//            if(lease != null){
//                lease.setUseState(2);
//                AssertUtil.isTrue(leaseService.updateById(lease), "更新失败");
//            }
//
//            // 更新合租总房间使用情况
//            if (squeryWapper == null) {
//                squeryWapper = new SqueryWapper<>(Lease.class);
//            }
//            QueryWrapper<Lease> wrapper = Wrappers.query();
//            List<String> f = new ArrayList<>();
//            f.add("roomId-eq~"+tenancyRoom.getRoomId());
//            f.add("useState-in~0~1");
//            squeryWapper.setWhere(f, wrapper);
//            List<Lease> list = leaseService.list(wrapper);
//            if(list.size() == 0){
//                Room room = roomService.getById(tenancyRoom.getRoomId());
//                if(room != null){
//                    room.setUseState(2);
//                    room.setIsFull(1);
//                    AssertUtil.isTrue(roomService.updateById(room), "更新失败");
//                }
//            }
//        }
        return HttpResult.success();
    }

    /**
     * 租房到期
     */
    @Transactional
    public HttpResult<Void> mature(Long id) {
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(id);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        tenancyRoom.setTenancyState(4);
        tenancyRoom.setContinueState(1);
        AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");
        return HttpResult.success();
    }

    /**
     * 续租申请
     */
    @Transactional
    public HttpResult<Void> continueApply(Long tenancyId) {
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(tenancyId);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        Room room = roomService.getById(tenancyRoom.getRoomId());
        if(room != null){
//            tenancyRoom.setWaitPay(room.getRent());
//            tenancyRoom.setContinuePay(room.getRent());
            tenancyRoom.setWaitPay(new BigDecimal(500));
            tenancyRoom.setContinuePay(new BigDecimal(500));
        }
        tenancyRoom.setContinueState(2);
        tenancyRoom.setContinueTime(LocalDateTime.now());
        AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");
        return HttpResult.success();
    }

    /**
     * 续租审核
     */
    @Transactional
    public HttpResult<Void> continueExamine(Long id,Integer continueState) {
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(id);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        //TODO 重新计算租金
        BigDecimal billAmount = new BigDecimal(99.99);
        if(continueState == 1){
            LocalDateTime now = LocalDateTime.now();
//            LocalDateTime endTime = now;
//            if(tenancyRoom.getPayWay() == 0){
//                endTime = now.plusMonths(1);
//            }else if(tenancyRoom.getPayWay() == 1){
//                endTime = now.plusMonths(3);
//            }else if(tenancyRoom.getPayWay() == 2){
//                endTime = now.plusMonths(6);
//            }else if(tenancyRoom.getPayWay() == 3){
//                endTime = now.plusMonths(12);
//            }
            tenancyRoom.setWaitPay(billAmount);
            tenancyRoom.setContinuePay(billAmount);
//            tenancyRoom.setAlreadyPay(tenancyRoom.getAlreadyPay().add(tenancyRoom.getWaitPay()));
//            tenancyRoom.setWaitPay(new BigDecimal(0));
            tenancyRoom.setTenancyState(2);
            tenancyRoom.setContinueState(5);
//            tenancyRoom.setFirstPayTime(now);
//            tenancyRoom.setEndTime(endTime);
            AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");

            // 生成账单
            Finance record = new Finance();
            record.setTenancyId(tenancyRoom.getId());
            record.setFormResultId(tenancyRoom.getFormResultId());
            record.setUserId(tenancyRoom.getUserId());
            record.setApplicantId(tenancyRoom.getApplicantId());
            record.setRoomId(tenancyRoom.getRoomId());
            record.setTenancyWay(tenancyRoom.getTenancyWay());
            record.setLeaseId(tenancyRoom.getLeaseId());
            record.setContractId(tenancyRoom.getContractId());
            record.setContractCode(tenancyRoom.getContractCode());
            record.setPayWay(tenancyRoom.getPayWay());
            record.setIsContinue(1);
//            record.setPayAmount(tenancyRoom.getContinuePay());
//            record.setPayTime(now);
//            record.setPayMode(0);
            record.setApplyTime(tenancyRoom.getContinueTime());
            record.setExamineTime(now);
            record.setCostType(1);
            record.setBillAmount(billAmount);
            record.setUnpaidAmount(billAmount);
            AssertUtil.isTrue(financeService.save(record), "创建失败");
        }else if(continueState == 9){
            tenancyRoom.setContinueState(9);
            AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");
        }
        return HttpResult.success();
    }

    /**
     * 退租申请
     */
    @Transactional
    public HttpResult<Void> exitTenancyApply(Long tenancyId) {
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(tenancyId);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }

//        User user = userService.getById(tenancyRoom.getUserId());
//        if (null == user){
//            System.out.println("===============1申请用户为空！");
//            return HttpResult.fail("B0000", I18n.build("申请用户为空！"));
//        }
        ClientUser user = clientUserService.getById(tenancyRoom.getUserId());
        if(user == null) {
            return HttpResult.fail("B0000", I18n.build("申请用户为空！"));
        }

        if (squeryWapperProcess == null) {
            squeryWapperProcess = new SqueryWapper<>(Process.class);
        }
        QueryWrapper<Process> wrapper = Wrappers.query();
        List<String> f = new ArrayList<>();
        f.add("examineType-eq~2");
        squeryWapperProcess.setWhere(f, wrapper);
        List<Process> list = processService.list(wrapper);
        if(list.size() <= 0){
            System.out.println("===============1退房审批流程为空！");
            return HttpResult.fail("B0000", I18n.build("退房审批流程为空！"));
        }

        ProcessApply apply = new ProcessApply();
        apply.setTenancyRoomId(tenancyRoom.getId());
        apply.setUserId(user.getId());
        apply.setUserName(user.getUserName());
        apply.setProcessId(list.get(0).getId());
        apply.setProcessName(list.get(0).getProcessName());
        return processApplyService.applyExamine(apply);
    }

    /**
     * 退租
     */
    @Transactional
    public HttpResult<Void> exitTenancy(Long id) {
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(id);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        tenancyRoom.setTenancyState(5);
        tenancyRoom.setContinueState(4);
        tenancyRoom.setExitTime(LocalDateTime.now());
        AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");

        // 更新房间使用情况
        if(tenancyRoom.getTenancyWay() == 0){
            // 更新整租房间使用情况
            Room room = roomService.getById(tenancyRoom.getRoomId());
            if(room != null){
                room.setUseState(0);
                if(tenancyRoom.getTenancyWay() == 0){
                    room.setIsFull(0);
                }
                AssertUtil.isTrue(roomService.updateById(room), "更新失败");
            }
        }else{
            // 更新合租房间使用情况
            Lease lease = leaseService.getById(tenancyRoom.getLeaseId());
            if(lease != null){
                lease.setUseState(0);
                AssertUtil.isTrue(leaseService.updateById(lease), "更新失败");
            }
            Room room = roomService.getById(tenancyRoom.getRoomId());
            if(room != null){
                room.setUseState(0);
                room.setIsFull(0);
                AssertUtil.isTrue(roomService.updateById(room), "更新失败");
            }
        }

        return HttpResult.success();
    }

    /**
     * 转租申请
     */
    @Transactional
    public HttpResult<Void> subletApply(Long id,String account) {
//        User user = userService.getByUsername(account);
//        if (null == user){
//            return HttpResult.fail("B0000", I18n.build("被转租用户为空！"));
//        }
        ClientUser user = clientUserService.selectByAccount(account);
        if(user == null) {
            return HttpResult.fail("B0000", I18n.build("被转租用户为空！"));
        }
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(id);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
//        User subletUser = userService.getById(tenancyRoom.getUserId());
//        if (null == user){
//            return HttpResult.fail("B0000", I18n.build("转租用户为空！"));
//        }
        ClientUser subletUser = clientUserService.getById(tenancyRoom.getUserId());
        if(user == null) {
            return HttpResult.fail("B0000", I18n.build("转租用户为空！"));
        }

        if (squeryWapperProcess == null) {
            squeryWapperProcess = new SqueryWapper<>(Process.class);
        }
        QueryWrapper<Process> wrapper = Wrappers.query();
        List<String> f = new ArrayList<>();
        f.add("examineType-eq~4");
        squeryWapperProcess.setWhere(f, wrapper);
        List<Process> list = processService.list(wrapper);
        if(list.size() <= 0){
            return HttpResult.fail("B0000", I18n.build("转租审批流程为空！"));
        }
        tenancyRoom.setSubletUserId(tenancyRoom.getUserId());
        tenancyRoom.setUserId(user.getId());
        tenancyRoom.setTenancyState(7);
        AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");

        ProcessApply apply = new ProcessApply();
        apply.setTenancyRoomId(tenancyRoom.getId());
        apply.setUserId(subletUser.getId());
        apply.setUserName(subletUser.getUserName());
        apply.setProcessId(list.get(0).getId());
        apply.setProcessName(list.get(0).getProcessName());
        return processApplyService.applyExamine(apply);
    }

    /**
     * 转租
     */
    @Transactional
    public HttpResult<Void> sublet(Long id) {
        // 更新租房情况
        TenancyRoom tenancyRoom = super.getById(id);
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        tenancyRoom.setTenancyState(3);
        AssertUtil.isTrue(super.updateById(tenancyRoom), "更新失败");

        // 新增租房记录
        TenancyRoomRecord record = new TenancyRoomRecord();
        record.setTenancyId(tenancyRoom.getId());
        record.setFormResultId(tenancyRoom.getFormResultId());
        record.setUserId(tenancyRoom.getUserId());
        record.setSubletUserId(tenancyRoom.getSubletUserId());
        record.setRoomId(tenancyRoom.getRoomId());
        record.setTenancyWay(tenancyRoom.getTenancyWay());
        record.setLeaseId(tenancyRoom.getLeaseId());
        record.setContractId(tenancyRoom.getContractId());
        record.setContractCode(tenancyRoom.getContractCode());
        record.setPayWay(tenancyRoom.getPayWay());
        record.setIsContinue(2);
        record.setMoveTime(LocalDateTime.now());
        record.setEndTime(tenancyRoom.getEndTime());
        AssertUtil.isTrue(recordService.save(record), "创建失败");

        return HttpResult.success();
    }

    @Override
    public TenancyRoom getData(Long id) {
        if (Objects.isNull(id)) {
            return new TenancyRoom();
        }
        return this.getOne(Wrappers.<TenancyRoom>lambdaQuery().eq(TenancyRoom::getId, id));
    }
}
